# -*- coding: utf-8 -*-
import os
import json
import pymysql
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
pymysql.install_as_MySQLdb()

from sqlalchemy import Column, String,Integer,DateTime, create_engine,ForeignKey
from sqlalchemy.orm import sessionmaker,relationship
from sqlalchemy.ext.declarative import declarative_base

current_path = os.path.dirname(os.path.abspath(__file__))
root_path = os.path.abspath( os.path.join(current_path, os.pardir))
config_path = os.path.join(root_path, 'config.json')
config = json.load(file(config_path, 'r'))
mysql_config=config["modules"]["mysql"]

try:
    connection=pymysql.connect(user=mysql_config["user"], password=mysql_config["pswd"], host=mysql_config["host"], port=mysql_config["port"])
    with connection.cursor() as cursor:
        cursor.execute(
        "CREATE DATABASE IF NOT EXISTS {db} DEFAULT CHARSET utf8 COLLATE utf8_general_ci;".format(db=mysql_config["db"])
        )
except pymysql.err.OperationalError as e:
    print "Exception",e

# 创建对象的基类:
Base = declarative_base()

# 定义User对象:
class User(Base):
    __tablename__ = 'user'

    id = Column(Integer,primary_key=True)
    user_name = Column(String(128),unique=True)
    pass_word = Column(String(128))
    paths = relationship('Permission',backref='user')
    create_time = Column(DateTime)

    def readabelFilterHandler(self,key):
        if not hasattr(self,"rcache"):
            self.rcache={}
        if key in self.rcache:
            return self.rcache[key]
        t=('/'+(key.strip('/'))).rstrip('/').split("/")
        tree=self.tree
        for i in t[1:]:
            if "*" in tree:
                self.rcache[key]="*"
                return "*"
            elif i not in tree:
                self.rcache[key]=False
                return None
            else:
                tree=tree[i]
        else:
            self.rcache[key]=tree
            return tree

    def writeableFilterHandler(self,key):
        """
        key is look like pathA/pathB/pathC
        """
        if not hasattr(self,"wcache"):
            self.wcache={}
        if key in self.wcache:
            return self.wcache[key]
        t=key.strip('/').rstrip('/').split("/")
        tree=self.tree
        for i in t:
            if "*" in tree:
                self.wcache[key]=True
                return True
            elif i not in tree:
                self.wcache[key]=False
                return False
            else:
                tree=tree[i]
        else:
            self.rcache[key]=False
            return False

# 定义Permission对象：
class Permission(Base):
    __tablename__ = "permission"
    id = Column(Integer,primary_key=True)
    user_id= Column(Integer,ForeignKey('user.id'))
    bucket_name = Column(String(128))
    path = Column(String(128))
    create_time = Column(DateTime)
    last_update_time = Column(DateTime)

# 初始化数据库连接:
db_url='mysql+mysqldb://{user}{pswd}@{host}:{port}/{db}'.format(
        user=mysql_config["user"],
        pswd=(":"+mysql_config["pswd"] if mysql_config["pswd"] != "" else ""),
        host=mysql_config["host"],
        port=mysql_config["port"],
        db=mysql_config["db"]
    )
try:
    engine = create_engine(db_url)
    DBSessionMaker = sessionmaker(bind=engine)
    #初始化数据库表
    Base.metadata.create_all(engine)
except Exception as e:
    print "Exception",e



def pathFilter(func):
    def wrapper(*args,**kwargs):
        user_obj=args[0].user_obj
        bucket_name=args[0].bucket_name
        target_path=unicode(args[1].replace("\\","/")[len(bucket_name)+1:])
        root_path=""
        result_set=set()
        start_permission_paths=set()
        for p in user_obj.paths:
            if p.path.endswith("*"):
                start_permission_paths.add(unicode(p.path[:-1]))
        print start_permission_paths
        res=func(*args, **kwargs)
        print func.__name__,target_path,res
        for result_path_tuple in res:
            try:
                result_path=target_path+u"/"+result_path_tuple[0]
                f1={i for i in start_permission_paths if i.startswith(result_path)}
                f2={i for i in start_permission_paths if result_path.startswith(i)}
                print result_path,f1,f2
                if len(f1) + len(f2) != 0 :
                    result_set.add(result_path_tuple)
            except Exception as e:
                print e
        return list(result_set)
    wrapper.__name__ = func.__name__
    return wrapper

def getUserObj(user_name):
    try:
        global DBSessionMaker
        session=DBSessionMaker()
        user_obj=session.query(User).filter_by(user_name=user_name).one()
        tree={}
        for i in user_obj.paths:
            t=i.path.split("/")
            parentTreeObj=tree
            parentPath=t[0]
            for j in t[1:]:
                if '*' in parentTreeObj:
                    break
                parentTreeObj=parentTreeObj.setdefault(j,{})
        user_obj.tree=tree
    except Exception as e:
        raise e  
    return user_obj

def writeFilePermissionFilter(func):
    def wrapper(*args,**kwargs):
        self=args[0]
        filename=args[1]
        key=filename.replace(os.sep,"/").replace(self.bucket_name,"",1)
        if self.user_obj is not None and not self.user_obj.writeableFilterHandler(key):
            print filename,"Permission deny"
            return
        else:    
            return func(*args,**kwargs)
    return wrapper